package com.wangzhen.spring.ioc.dependcy.loopup;

import com.wangzhen.spring.ioc.dependcy.entity.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;

/**
 * bean查找是否安全演示
 * 1、BeanFactory#getBean 不安全（当查找的bean在context中不存在时会发生异常）
 * 2、ObjectFactory#getObject 不安全
 * 3、ObjectProvider#getIfAvailable 安全
 * 4、ObjectProvider#stream 安全
 * 5、ListableBeanFactory#getBeansOfType 安全
 *
 */
public class SafetyDependencyLookUpDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(SafetyDependencyLookUpDemo.class);
        // 启动应用上下文
        applicationContext.refresh();
        // 演示一：通过BeanFactory#getBean的方式获取bean(不安全，如果bean不存在会抛出异常)
        displayBeanFactoryGetBean(applicationContext);
        // 演示二：通过ObjectFactory#getObject的方式获取bean(不安全，如果bean不存在会抛出异常)
        displayObjectFactoryGetObject(applicationContext);

        // 演示三： 通过ListableBeanFactory#getBeansOfType方式获取bean(安全)
        displayListableBeanFactoryGetBeansOfType(applicationContext);
        // 演示四： 通过ObjectProvider#getIfAvailable方式获取bean(安全)
        displayObjectProviderGetIfAvailable(applicationContext);
        // 演示五： 通过ObjectProvider#stream方式获取bean(安全)
        displayObjectProviderStream(applicationContext);

        applicationContext.close();
    }

    private static void displayObjectProviderStream(AnnotationConfigApplicationContext applicationContext) {
        ObjectProvider<User> beanProvider = applicationContext.getBeanProvider(User.class);
        beanProvider.stream().forEach(System.out::println);
    }

    private static void displayObjectProviderGetIfAvailable(AnnotationConfigApplicationContext applicationContext) {
        ObjectProvider<User> beanProvider = applicationContext.getBeanProvider(User.class);
        System.out.println(beanProvider.getIfAvailable());
    }

    private static void displayListableBeanFactoryGetBeansOfType(ListableBeanFactory applicationContext) {
        System.out.println(applicationContext.getBeansOfType(User.class));
    }

    private static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext applicationContext) {
        try {
            ObjectFactory<User> objectFactory = applicationContext.getBeanProvider(User.class);
            System.out.println(objectFactory.getObject());
        } catch (Exception e) {
            System.out.println("displayObjectFactoryGetObject 发生异常了！");
            e.printStackTrace();
        }
    }

    private static void displayBeanFactoryGetBean(AnnotationConfigApplicationContext applicationContext) {
        try {
            System.out.println(applicationContext.getBean(User.class));
        } catch (Exception e) {
            System.out.println("displayBeanFactoryGetBean 发生异常了！");
            e.printStackTrace();
        }
    }


}
